package edu.pku.sei.modeler.uml.commands.timing;

import org.eclipse.draw2d.geometry.Point;
import org.eclipse.gef.commands.Command;

import edu.pku.sei.modeler.exceptions.FactoryNotFoundException;
import edu.pku.sei.modeler.model.common.ModelRegistry;
import edu.pku.sei.modeler.model.structure.MetaBendPoint;
import edu.pku.sei.modeler.model.structure.MetaLink;
import edu.pku.sei.modeler.model.structure.StructureFactory;

public class TimeLineMoveLinearCommand extends Command {
	private MetaLink link;
	private int index;
	private MetaBendPoint oldLeftBendpoint, oldRightBendpoint, newLeftBendpoint, newRightBendpoint;
	private Point right,left;
	private Point location;
		
	public TimeLineMoveLinearCommand(MetaLink link, Point location, int index, Point left, Point right) {
		super("Move Bendpoint");
		this.link = link;
		this.index = index;
		this.location = location;
		if (index == 1)
			this.left = left;
		else this.left = ((MetaBendPoint)link.getBendPoints().get(index - 2)).getLocation();
		if (index == link.getBendPoints().size() - 1)
			this.right = right;
		else 
			this.right = ((MetaBendPoint)link.getBendPoints().get(index + 1)).getLocation();
		StructureFactory sFactory;
		try {
			sFactory = (StructureFactory)ModelRegistry.getRegistry().getStructureFactory(link.getModelElement().getModel());
			newLeftBendpoint = sFactory.createMetaBendPoint();
			newRightBendpoint = sFactory.createMetaBendPoint();
			
			
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (FactoryNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		oldLeftBendpoint = (MetaBendPoint)link.getBendPoints().get(index - 1);
		oldRightBendpoint = (MetaBendPoint)link.getBendPoints().get(index);
	}

	public boolean canExecute() {
		return link != null && index >= 0 && newRightBendpoint != null && oldRightBendpoint != null
		&& newLeftBendpoint != null && oldLeftBendpoint != null;
	}
		
	public void execute() {
		if (oldLeftBendpoint.y == oldRightBendpoint.y) {
			newLeftBendpoint.x = oldLeftBendpoint.x;
			newLeftBendpoint.y = location.y;
			newRightBendpoint.x = oldRightBendpoint.x;
			newRightBendpoint.y = location.y;
		} else {
			int offset = location.x - (oldLeftBendpoint.x + oldRightBendpoint.x)/2;
			if (offset < left.x - oldLeftBendpoint.x)
				offset = left.x - oldLeftBendpoint.x;
			else if (offset > right.x - oldRightBendpoint.x)
				offset = right.x - oldRightBendpoint.x;
			
			newLeftBendpoint.x = oldLeftBendpoint.x + offset;
			newLeftBendpoint.y = oldLeftBendpoint.y;
			newRightBendpoint.x = oldRightBendpoint.x + offset;
			newRightBendpoint.y = oldRightBendpoint.y;
		}
		link.getBendPoints().set(index - 1, newLeftBendpoint);
		link.getBendPoints().set(index, newRightBendpoint);
	}

	public void undo() {
		link.getBendPoints().set(index - 1, oldLeftBendpoint);
		link.getBendPoints().set(index, oldRightBendpoint);
	}
}
